<?php
/**
 * Created by PhpStorm.
 * User: admin
 * Date: 2019/11/12
 * Time: 17:07
 */

namespace app\adminapiv3\service;


use app\common\service\IpsType;
use think\Db;

class IpsRule extends Base
{

    /**
     * @name: ips规则选项数据
     * @Param: 
     * @Description: 
     * @Author: foo
     * @Date: 2020-10-30 10:26:28
     */
    function data()
    {
        $data = db('ips_type')->where('type','freeRule')->field('id, show_name')->select();

        return $data;
    }

    /**
     * @name 列表
     * @param $host_id
     * @param $params
     * @param int $limit
     * @return array
     * @author wx
     * @date 2019/11/13 10:40
     */
    function list($host_id, $params, $limit = 10)
    {

        $server = new \app\common\service\IpsRule();
        $list = $server->list($host_id, $params, $limit);

        return $list;
    }


    /**
     * @name 修改状态
     * @param $id
     * @param $updateData
     * @return bool
     * @author wx
     * @date 2019/11/13 10:43
     */
    function modifyStatus($host_id, $id, $updateData)
    {
        $this->checkOptionHost($host_id);

        $server = new \app\common\service\IpsRule();
        $server->modify(['host_id' => $host_id, 'id' => $id], $updateData);
        $server->modify(['host_id' => $host_id, 'fid' => $id], $updateData);


        return true;
    }

    /**
     * @name 修改
     * @param $host_id
     * @param $id
     * @param $updateData
     * @author wx
     * @date 2020/7/22 13:23
     */
    function modify($host_id, $id, $updateData){
        $this->checkOptionHost($host_id);


        //验证重复
        $count = db('ips_rule')
            ->where('id', '<>', $id)
            ->where('host_id', $updateData['host_id'])
            ->where('content', $updateData['content'])
            ->where('type', $updateData['type'])
            ->count();

        if($count){
            returnErrJson($this->CODE_FAIL, '自定义规则重复');
        }


        //删除额外的数据
        db('ips_rule')->where('id', $id)->delete();
        db('ips_rule')->where('fid', $id)->delete();

        $this->add($updateData);


    }

    /**
     * @name 删除
     * @param $id
     * @return bool
     * @author wx
     * @date 2019/11/13 10:50
     */
    function del($host_id, $id)
    {
        $this->checkOptionHost($host_id);

        //将ip限制的ip查询出来
        $srcIpArr = Db::name('ips_type it')->join('ips_rule ir', 'it.id = ir.type')
            ->where('ir.id', 'in', $id)
            ->where('it.show_name','IP限制')
            ->where('ir.host_id',$host_id)
            ->column('ir.content');

        //将需要删除的ip自定义规则置为0
        Db::name('network_attack')->where('host_id', $host_id)->where('src_ip','in',$srcIpArr)->update(['allow_ip_rule_id' => 0]);


        $server = new \app\common\service\IpsRule();
        $condition[] = array('id', 'in', $id);
        $server->del($condition);
        $condition1[] = array('fid', 'in', $id);
        $server->del($condition1);



        return true;
    }

    /**
     * @name 清空
     * @param $clear
     * @return bool
     * @author wx
     * @date time
     */
    function clear($host_id, $clear)
    {
        $this->checkOptionHost($host_id);

        if ($clear != 1) {
            $this->setError($this->CODE_FAIL, '参数错误');
            return false;
        }

        //将ip限制的ip查询出来
        $srcIpArr = Db::name('ips_type it')->join('ips_rule ir', 'it.id = ir.type')
            ->where('it.show_name','IP限制')
            ->where('ir.host_id',$host_id)
            ->column('ir.content');

        //将需要删除的ip自定义规则置为0
        Db::name('network_attack')->where('host_id', $host_id)->where('src_ip','in',$srcIpArr)->update(['allow_ip_rule_id' => 0]);


        $server = new \app\common\service\IpsRule();
        $condition['host_id'] = $host_id;
        $server->del($condition);

        return true;
    }


    /**
     * @name 添加
     * @param $addData
     * @author wx
     * @date 2019/11/13 16:48
     */
    function add($addData)
    {
        $this->checkOptionHost($addData['host_id']);

        $typeServer = new IpsType();

        //1.验证限制类型
        $typeArr = $typeServer->findData(['id' => $addData['type'], 'type' => 'freeRule']);

        if(empty($typeArr)){
            $this->setError($this->CODE_FAIL, '规则类型错误!');
            return false;
        }

        $count = db('ips_rule')
            ->where('host_id', $addData['host_id'])
            ->where('content', $addData['content'])
            ->where('type', $addData['type'])
            ->count();

        if($count){
            $this->setError($this->CODE_FAIL, '自定义规则重复!');
            return false;
        }

        $addData['ctime'] = time();
        $addData['execute_content'] = '';

        $server = new \app\common\service\IpsRule();
        $insertId = $server->add($addData);

        $sid = $this->createSid($insertId);

        $updateData = [
            'execute_content' => $this->encryptRule($sid, $addData),
            'sid' => $sid
        ];
        $server->modify(['id' => $insertId], $updateData);


        if($typeArr['show_name'] == '请求文件限制'){
            $this->addExtraRule($insertId, $addData, 'user-request-file-limit_gbk');
        }elseif ($typeArr['show_name'] == '返回内容限制'){
            $typeArray = array(
                'user-response-content-limit_gbk',
                'user-response-content-limit_url',
                'user-response-content-limit_utf8',
            );

            foreach ($typeArray as $v){
                $this->addExtraRule($insertId, $addData, $v);
            }
        }

        return true;

    }

    /**
     * @name 加密规则
     * @param
     * @param $data
     * @return string
     * @author wx
     * @date 2020/7/23 13:30
     */
    function encryptRule($sid, $data)
    {
        if (is_numeric($data['type'])) {
            $typeStr = db('ips_type')->where('id', $data['type'])->value('key');
        }else{
            $typeStr = $data['type'];
        }


        $encryData['classtype'] = $typeStr;
        $encryData['sid'] = $sid;
        $encryData['content'] = $data['content'];
        $encryData['description'] = $data['description'];
        $encryData['intranet'] = $data['intranet'] ? true : false;

        $str = base64_encode(json_encode($encryData));

        return $str;

    }

    /**
     * @name 生成额外规则
     * @param $fid
     * @param $data
     * @param $type
     * @author wx
     * @date 2020/7/21 11:01
     */

    function addExtraRule($fid, $data, $type)
    {

        $data['fid'] = $fid;
        $data['ctime'] = time();

        $server = new \app\common\service\IpsRule();
        $newId = $server->add($data);
        $sid = $this->createSid($newId);

        $data['type'] = $type;
        $updateData = [
            'execute_content' => $this->encryptRule($sid, $data),
            'sid' => $sid
        ];

        $server->modify(['id' => $newId], $updateData);
    }


    /**
     * @name 创建sid
     * @param $host_id
     * @return int|mixed
     * @author wx
     * @date 2020/7/20 16:31
     */
    function createSid($insertId)
    {
        $sid = 600000000 + $insertId;

        return $sid;
    }

}